package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.ConfigConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.errorcodes.PayErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.service.toolbox.statistic.help.SystemChartHelp;
import com.xbongbong.pro.sheet.pojo.AmountDetailGetPojo;
import com.xbongbong.pro.user.pojo.UserTypePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.PaymentBalanceInsertConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.PayBalanceEntity;
import com.xbongbong.saas.domain.entity.PayBalanceUserEntity;
import com.xbongbong.saas.domain.entity.PayPlanSheetUserEntity;
import com.xbongbong.saas.domain.entity.SupplierUserEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.PayBalanceModel;
import com.xbongbong.saas.model.PayBalanceUserModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PayPlanSheetUserModel;
import com.xbongbong.saas.model.PurchaseUserModel;
import com.xbongbong.saas.model.SupplierUserModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author: 汪腾伟
 * @date: Created in 2021/9/15 11:28
 * @description： 适配工作流这边的付款单帮助类
 */
@Component
public class SaasPaySheetHelper {

    private static final Logger LOG = LoggerFactory.getLogger(SaasPaySheetHelper.class);

    @Resource
    private PayBalanceModel payBalanceModel;
    @Resource
    private SystemChartHelp systemChartHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private SupplierUserModel supplierUserModel;
    @Resource
    private PayBalanceUserModel payBalanceUserModel;
    @Resource
    private PayPlanSheetUserModel payPlanSheetUserModel;
    @Resource
    private PurchaseUserModel purchaseUserModel;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;

    /**
     * 判断前端输入的预付款核销、红冲预付款余额类型付款单的金额是否超过供应商余额
     * @param dataList 付款单data
     * @param corpid 公司id
     * @param sheetAmount 付款单金额（红冲预付款余额的红冲金额、预付款核销的核销金额）
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void checkBalance(JSONObject dataList, String corpid, Double sheetAmount) throws XbbException {
        //预付款核销，要控制金额小于供应商余额
        Long supplierId = FastJsonHelper.getLongOrDefaultFromFormData(dataList, PaySheetEnum.LINK_SUPPLIER.getAttr(), 0L);
        PayBalanceEntity payBalanceEntity = payBalanceModel.getBySupplierId(supplierId, corpid);
        //如果供应商预付款余额不足，则不能保存成功
        boolean nonEmptyFlag = payBalanceEntity != null && payBalanceEntity.getAdvancePaymentBalance() != null;
        boolean over = nonEmptyFlag && Arith.sub(sheetAmount , payBalanceEntity.getAdvancePaymentBalance()) > ConfigConstant.amountAccuracy;
        if (over) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.DETAIL_BEYOND_BALANCE_PAY_RED);
        }
    }

    /**
     * 计算付款单已经红冲的总金额，即求和关联原始付款单id为sheetId的付款单的红冲金额
     * 注：此方法未对红冲金额求正值，因此此时的红冲金额还为负数
     * @param corpid 公司id
     * @param sheetId 付款单id
     * @return double
     * @throws XbbException
     * @author zcp
     * @date 19/12/8 008 16:38
     * @update 19/12/8 008 16:38
     * @since v1.0
     * @version v1.0
     */
    public double sumRedAmountBySheet(String corpid, Long sheetId) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = getBoolQueryBuilder4LinkRed(corpid, Collections.singletonList(sheetId));
        boolQueryBuilder.filter(termsQuery(StringConstant.FLOW_STATUS, Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        //聚合得到该条付款单（sheetId）关联的已红冲付款单总额
        return systemChartHelp.getDouble4Total(IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET, boolQueryBuilder, PaySheetEnum.getAttrConnectData(PaySheetEnum.AMOUNT));
    }

    /**
     * 原始付款单的关联红冲付款单的查询条件
     * @param corpid 公司id
     * @param sheetIdIn 原单id集合
     * @return org.elasticsearch.index.query.BoolQueryBuilder
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public BoolQueryBuilder getBoolQueryBuilder4LinkRed(String corpid, List<Long> sheetIdIn) {
        // 查询该付款计划下面关联的所有付款单
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType())));
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        //限制alone
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.SHEET_ALONE.getAlias(), SheetAloneEnum.getNotChildCodeList()));
        //限制关联原始付款单id为sheetId
        boolQueryBuilder.filter(termsQuery(PaySheetEnum.getEsAttr4Keyword(PaySheetEnum.ORIGIN_ID), sheetIdIn));
        //只读红冲类型付款单
        boolQueryBuilder.filter(termsQuery(PaySheetEnum.getEsAttr4Keyword(PaySheetEnum.PAY_SHEET_TYPE), PaySheetTypeEnum.getRedCodeList()));
        return boolQueryBuilder;
    }

    /**
     * 得到原单的已红冲总金额，并查询原单关联的已红冲单据封装成purchaseId_payPlanId 和 红冲金额的对应关系map（如果有子单则得到子单的对应关系）
     * 注：此方法未对红冲金额求正值，因此此时的红冲金额还为负数
     * @param corpid 公司id
     * @param sheetId 原单id
     * @param amountDetailGetPojo 获取金额明细时需要用到的条件、原单信息pojo
     * @return java.util.Map<java.lang.String,java.lang.Double>
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public Map<String, Double> handleRedSheetsBySheet(String corpid, Long sheetId, AmountDetailGetPojo amountDetailGetPojo) throws XbbException {
        // 查询该付款计划下面关联的所有付款单
        BoolQueryBuilder boolQueryBuilder = getBoolQueryBuilder4LinkRed(corpid, Collections.singletonList(sheetId));
        List<String> fieldList = Arrays.asList(BasicConstant.ID, BasicConstant.DATAID, FieldTypeEnum.SHEET_ALONE.getAlias(), FieldTypeEnum.SHEET_UUID.getAlias(), PaySheetEnum.getAttrConnectData(PaySheetEnum.PAY_SHEET_TYPE), PaySheetEnum.getAttrConnectData(PaySheetEnum.AMOUNT), PaySheetEnum.getAttrConnectData(PaySheetEnum.WRITE_OFF_AMOUNT), PaySheetEnum.getAttrConnectData(PaySheetEnum.LINK_PURCHASE), PaySheetEnum.getAttrConnectData(PaySheetEnum.PAY_PLAN));
        //分页查询
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = esHelper.findByPage(IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList, BasicConstant.ONE, EsNormalConstant.FIND_NUM, null);
        List<PaasFormDataEntityExt> sheetList = new ArrayList<>();
        if (esEntities != null) {
            sheetList = esEntities.getContent();
        }
        Set<String> uuidSet = new HashSet<>();
        /**
         key：红冲付款单的采购合同id_付款计划id
         value：红冲单据的金额
         */
        Map<String, Double> redCidPidAmountMap = new HashMap<>(sheetList.size());
        Double sumAmount = 0D;
        for (PaasFormDataEntityExt entityExt : sheetList) {
            JSONObject data = entityExt.getData();
            String paySheetType = FastJsonHelper.getStringFromFormData(data, PaySheetEnum.PAY_SHEET_TYPE.getAttr());
            double sheetAmount = FundHelp.getSheetAmount4PaySheet(data, paySheetType);
            sumAmount = Arith.add(sumAmount, sheetAmount);
            if (Objects.equals(entityExt.getAlone(), SheetAloneEnum.NORMAL.getCode())) {
                fundHelp.formatCidPidRedAmountMap(PaySheetEnum.LINK_PURCHASE.getAttr(), PaySheetEnum.PAY_PLAN.getAttr(), redCidPidAmountMap, entityExt, sheetAmount);
                continue;
            } else {
                //父单，则读取子单
                uuidSet.add(entityExt.getUuid());
            }
        }
        amountDetailGetPojo.setRedAmount(sumAmount);
        //如果有明细，则处理明细
        List<PaasFormDataEntityExt> childList = fundHelp.getChildEsDataListByParentUuids(XbbRefTypeEnum.PAY_SHEET, corpid, uuidSet, null, null);
        for (PaasFormDataEntityExt entityExt : childList) {
            JSONObject data = entityExt.getData();
            String paySheetType = FastJsonHelper.getStringFromFormData(data, PaySheetEnum.PAY_SHEET_TYPE.getAttr());
            double sheetAmount = FundHelp.getSheetAmount4PaySheet(data, paySheetType);
            fundHelp.formatCidPidRedAmountMap(PaySheetEnum.LINK_PURCHASE.getAttr(), PaySheetEnum.PAY_PLAN.getAttr(), redCidPidAmountMap, entityExt, sheetAmount);
        }
        amountDetailGetPojo.setRedCidPidAmountMap(redCidPidAmountMap);
        return redCidPidAmountMap;
    }


    public void saveBySheet(PayPlanSheetEntityExt payPlanSheetEntityExt) throws XbbException {
        try {
            JSONObject data = payPlanSheetEntityExt.getData();
            String paymentSheetTypeStr = data.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
            PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByCode(paymentSheetTypeStr);
            Double advancePayBalance;
            //只包含3种，为什么不包含“”红冲预付款核销: 直接把钱退给供应商，不退回预付款余额
            switch (paySheetTypeEnum) {
                case PREPAY:
                case RED_PREPAY:
                    //红冲预付款存储的是负值可直接使用
                    advancePayBalance = data.getDoubleValue(PaySheetEnum.AMOUNT.getAttr());
                    break;
                case WRITE_OFF_PREPAY:
                    advancePayBalance = data.getDoubleValue(PaySheetEnum.WRITE_OFF_AMOUNT.getAttr());
                    //核销金额要用余额减去
                    advancePayBalance = Arith.mul(advancePayBalance,-1D);
                    break;
                default:
                    LOG.error(paySheetTypeEnum.getAlias() + PayErrorCodeEnum.API_ERROR_226018.getMsg());
                    throw  new XbbException(PaymentErrorCodeEnum.API_ERROR_208029);
            }
            Long supplierId = data.getLong(PaySheetEnum.LINK_SUPPLIER.getAttr());
            String supplierName = data.getString(PaySheetEnum.SUPPLIER_LINK_TEXT.getAttr());
            String corpid = payPlanSheetEntityExt.getCorpid();
            PayBalanceEntity payBalanceEntity = payBalanceModel.getBySupplierId(supplierId, corpid);
            if(payBalanceEntity == null){
                if(advancePayBalance < 0 ){
                    throw  new XbbException(PaymentErrorCodeEnum.API_ERROR_208041);
                }
                payBalanceEntity = new PayBalanceEntity();
                payBalanceEntity.setCorpid(corpid);
                String value = paasRedisHelper.getValue(RedisPrefixConstant.PAY_BALANCE_FORM, corpid);
                PaasFormEntityExt paasFormEntity;
                if(StringUtil.isNotEmpty(value)){
                    paasFormEntity = JsonHelperUtil.parseObject(value,PaasFormEntityExt.class);
                }else{
                    paasFormEntity  = paasFormModel.getByBusinessType(XbbRefTypeEnum.PREPAY_BALANCE.getCode(), corpid,"id,app_id,menu_id");
                    paasRedisHelper.setValue(RedisPrefixConstant.PAY_BALANCE_FORM,corpid,paasFormEntity, RedisConstant.TINY_DURATION);
                }
                payBalanceEntity.setAppId(paasFormEntity.getAppId());
                payBalanceEntity.setMenuId(paasFormEntity.getMenuId());
                payBalanceEntity.setFormId(paasFormEntity.getId());
                //以下字段来自回款单
                payBalanceEntity.setOwnerId(payPlanSheetEntityExt.getOwnerId());
                payBalanceEntity.setDepartmentId(payPlanSheetEntityExt.getDepartmentId());
                payBalanceEntity.setSupplierId(supplierId);
                payBalanceEntity.setSupplierName(supplierName);
                payBalanceEntity.setAdvancePayBalance(advancePayBalance);
                payBalanceEntity.setCreatorId(payPlanSheetEntityExt.getCreatorId());
                long now = DateUtil.getNow();
                payBalanceEntity.setAddTime(now);
                payBalanceEntity.setUpdateTime(now);
                payBalanceEntity.setDel(0);
                Integer insert = payBalanceModel.insert(payBalanceEntity);
                if(Objects.equals(PaymentBalanceInsertConstant.INSERT,insert)){
                    //插入团队
                    insertBalanceUser(supplierId, corpid, payBalanceEntity);
                }
                //更新团队  更新不在此处处理  在供应商团队更新处处理
            }else{
                if(Arith.add(advancePayBalance,payBalanceEntity.getAdvancePayBalance()) < 0 ){
                    throw  new XbbException(PayErrorCodeEnum.API_ERROR_226015);
                }
                payBalanceEntity.setAdvancePayBalance(advancePayBalance);
                //删除后的重建
                boolean updateDel = false;
                if(Objects.equals(payBalanceEntity.getDel(),1)){
                    payBalanceEntity.setDel(0);
                    updateDel = true;
                }
                payBalanceModel.update(payBalanceEntity,updateDel);
                //删除后的重建
                if(updateDel){
                    insertBalanceUser(supplierId, corpid, payBalanceEntity);
                }
                //更新团队  更新不在此处处理  在供应商团队更新处处理
            }
        } catch (XbbException e) {
            throw  e;
        }catch (Exception e){
            LOG.error(PayErrorCodeEnum.API_ERROR_226015.getMsg() ,e);
            throw new XbbException(PayErrorCodeEnum.API_ERROR_226015);
        }
    }

    /**
     * 处理预付款余额团队
     * @param supplierId 供应商id
     * @param corpid 公司id
     * @param payBalanceEntity 预付款余额实体
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void insertBalanceUser(Long supplierId, String corpid, PayBalanceEntity payBalanceEntity) throws XbbException {
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(ParameterConstant.CORPID,corpid);
        map.put(BasicConstant.DATAID,supplierId);
        map.put(StringConstant.DEL,BasicConstant.ZERO);
        List<SupplierUserEntity> supplierUserList = supplierUserModel.findEntitys(map);
        if(CollectionsUtil.isNotEmpty(supplierUserList)){
            List<PayBalanceUserEntity> payBalanceUserEntityList = new ArrayList<>(supplierUserList.size());
            for (SupplierUserEntity supplierUserEntity : supplierUserList) {
                PayBalanceUserEntity  payBalanceUserEntity = new PayBalanceUserEntity();
                BeanUtil.copyProperties(supplierUserEntity,payBalanceUserEntity);
                payBalanceUserEntity.setSupplierId(supplierUserEntity.getDataId());
                payBalanceUserEntity.setDataId(payBalanceEntity.getId());
                payBalanceUserEntityList.add(payBalanceUserEntity);
            }
            payBalanceUserModel.insertBatch(payBalanceUserEntityList);
        }
    }

    /**
     * 处理付款单团队
     * @param dataList 付款单data
     * @param corpid 公司id
     * @param sheetTypeEnum
     * @param planSheetEntityExt 父付款单
     * @param sheetList 要处理团队的付款单list
     * @param ignoreMainSheet 是否忽略添加父回款单
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void handleSheetTeam(JSONObject dataList, String corpid, SheetTypeEnum sheetTypeEnum, PayPlanSheetEntityExt planSheetEntityExt, List<PayPlanSheetEntityExt> sheetList, boolean ignoreMainSheet) throws XbbException {
        if (ignoreMainSheet) {
            sheetList.add(planSheetEntityExt);
        }
        Long supplierId = dataList.getLong(PaySheetEnum.LINK_SUPPLIER.getAttr());
        Map<Long, List<Long>> sheetIdAndDataIdMap = new HashMap<>(sheetList.size());
        List<Long> contractIdIn = new ArrayList<>();
        String attrCon = PaySheetEnum.LINK_PURCHASE.getAttr();
        for (PayPlanSheetEntityExt entityExt : sheetList){
            fundHelp.handleSheetIdAndContractIdMap(contractIdIn, sheetIdAndDataIdMap, entityExt, attrCon);
        }
        createPaySheetUser(corpid, supplierId, contractIdIn, sheetIdAndDataIdMap, sheetTypeEnum, false);
    }

    /**
     *
     * @param corpid 公司编号
     * @param supplierId 供应商编号
     * @param purchaseIdIn 采购合同编号
     * @param sheetIdAndDataIdMap <付款单编号,采购合同/供应商编号>
     * @param sheetTypeEnum 付款单类型
     * @param parentNew 采购合同是否新建
     * @return
     * @throws XbbException
     */
    public BaseVO createPaySheetUser(String corpid, Long supplierId, List<Long> purchaseIdIn, Map<Long, List<Long>> sheetIdAndDataIdMap, SheetTypeEnum sheetTypeEnum, Boolean parentNew) throws XbbException {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("del",DelEnum.NORMAL.getDel());
        List<UserTeamEntity> userTeamEntityList;
        if ( SheetTypeEnum.noBelong(sheetTypeEnum) || parentNew) {
            map.put("supplierId",supplierId);
            userTeamEntityList = supplierUserModel.findBaseEntitys(map);
        }else {
            map.put("purchaseIdIn",purchaseIdIn);
            userTeamEntityList = purchaseUserModel.findBaseEntitys(map);
        }
        Map<Long, UserTypePojo> paySheetIdMap = getSetUserTeamEntityMap(userTeamEntityList,sheetIdAndDataIdMap);
        if (  !paySheetIdMap.isEmpty()) {
            List<PayPlanSheetUserEntity> payPlanSheetUserEntityList = new ArrayList<>();
            for ( Map.Entry<Long, UserTypePojo> sheetIdAndUser : paySheetIdMap.entrySet() ) {
                Long paySheetId = sheetIdAndUser.getKey();
                UserTypePojo userTypePojo = sheetIdAndUser.getValue();
                if ( Objects.nonNull(userTypePojo.getMainUserList()) ) {
                    for ( UserTeamEntity entity : userTypePojo.getMainUserList() ) {
                        PayPlanSheetUserEntity payPlanSheetUserEntity = new PayPlanSheetUserEntity();
                        BeanUtil.copyProperties(entity, payPlanSheetUserEntity);
                        payPlanSheetUserEntity.setId(null);
                        payPlanSheetUserEntity.setIsMain(BasicConstant.MAIN_USER);
                        payPlanSheetUserEntity.setDataId(paySheetId);
                        payPlanSheetUserEntityList.add(payPlanSheetUserEntity);
                    }
                }
                if ( Objects.nonNull(userTypePojo.getCoorUserList()) ) {
                    for ( UserTeamEntity entity : userTypePojo.getCoorUserList() ) {
                        PayPlanSheetUserEntity payPlanSheetUserEntity = new PayPlanSheetUserEntity();
                        BeanUtil.copyProperties(entity, payPlanSheetUserEntity);
                        payPlanSheetUserEntity.setId(null);
                        payPlanSheetUserEntity.setIsMain(BasicConstant.COOP_USER);
                        payPlanSheetUserEntity.setDataId(paySheetId);
                        payPlanSheetUserEntityList.add(payPlanSheetUserEntity);
                    }
                }
            }
            if (!payPlanSheetUserEntityList.isEmpty()) {
                payPlanSheetUserModel.insertBatch(payPlanSheetUserEntityList);
            }
        }
        return new BaseVO();
    }

    private Map<Long, UserTypePojo> getSetUserTeamEntityMap(List<UserTeamEntity> userTeamEntityList, Map<Long, List<Long>> sheetIdAndDataIdMap ){
        Map<Long, UserTypePojo> dataIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (UserTeamEntity userTeamEntity : userTeamEntityList) {
            UserTypePojo userTypePojo = dataIdMap.get(userTeamEntity.getDataId())!=null?dataIdMap.get(userTeamEntity.getDataId()):new UserTypePojo();
            if ( Objects.equals(userTeamEntity.getIsMain(),BasicConstant.MAIN_USER) ){
                userTypePojo.getMainUserList().add(userTeamEntity);
            } else {
                userTypePojo.getCoorUserList().add(userTeamEntity);
            }
            dataIdMap.put(userTeamEntity.getDataId(),userTypePojo);
        }
        Map<Long,UserTypePojo> paySheetIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //todo chenshan需要处理一下在不同合同人上即时负责人又是协同人
        for ( Map.Entry<Long, List<Long>> sheetIdAndDataId : sheetIdAndDataIdMap.entrySet() ) {
            List<Long> dataIds = sheetIdAndDataId.getValue();
            Long paySheetId = sheetIdAndDataId.getKey();
            UserTypePojo newUserTypePojo = new UserTypePojo();
            List<UserTeamEntity> newMainUserList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<UserTeamEntity> newCoorUserList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<String> userIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for ( Long dataId : dataIds ) {
                UserTypePojo userTypePojo = dataIdMap.get(dataId);
                if ( Objects.nonNull(userTypePojo) ) {
                    List<UserTeamEntity> mainUserList = userTypePojo.getMainUserList();
                    List<UserTeamEntity> coorUserList = userTypePojo.getCoorUserList();
                    for ( UserTeamEntity userTeamEntity : mainUserList ) {
                        if ( !userIdIn.contains(userTeamEntity.getUserId()) ) {
                            newMainUserList.add(userTeamEntity);
                            userIdIn.add(userTeamEntity.getUserId());
                        }
                    }
                    for ( UserTeamEntity userTeamEntity : coorUserList ) {
                        if ( !userIdIn.contains(userTeamEntity.getUserId()) ) {
                            newCoorUserList.add(userTeamEntity);
                        }
                    }
                }
            }
            newUserTypePojo.setMainUserList(newMainUserList);
            newUserTypePojo.setCoorUserList(newCoorUserList);
            paySheetIdMap.put(paySheetId, newUserTypePojo);
        }
        return paySheetIdMap;
    }

    /**
     * 插入子付款单，并置父付款单的alone值
     * （1）金额大于0的明细超过1条，才会加子付款单，且才会把子付款单的采购合同、付款、归属人信息合并置入父付款单
     * （2）金额大于0的明细只有1条，没必要再存一条子付款单（详情展示时，会特殊处理alone=1的，把父本身模拟出一条子明细）
     *
     * @param corpid 公司id
     * @param sonSheetDataList 子付款单数据data list
     * @param payPlanSheetEntityExt 父付款单实体
     * @param uuid 同分组uuid
     * @return java.util.List<com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt>
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public List<PayPlanSheetEntityExt> saveSheetSon(String corpid, List<JSONObject> sonSheetDataList, PayPlanSheetEntityExt payPlanSheetEntityExt, String uuid) throws XbbException {
        List<PayPlanSheetEntityExt> sonSheetList = new ArrayList<>();
        try {
            /**
             金额大于0的明细超过1条，才会加子付款单，且才会把子付款单的采购合同、付款、归属人信息合并置入父付款单
             金额大于0的明细只有1条，没必要再存一条子付款单（详情展示时，会特殊处理alone=1的，把父本身模拟出一条子明细）
             */
            if (sonSheetDataList.size() > BasicConstant.ONE) {
                String sonSerialNo = payPlanSheetEntityExt.getSerialNo() + SymbolConstant.POINT_ENGLISH;
                //子付款单的批量新增
                for (int i = 1; i <= sonSheetDataList.size(); i++) {
                    JSONObject sonData = sonSheetDataList.get(i - 1);
                    PayPlanSheetEntityExt sonSheetEntityExt = new PayPlanSheetEntityExt();
                    if (sonData != null) {
                        sonData.remove(PaasConstant.RETURNED_PURCHASE_ID);
                        FormDataUtil.removeSystemData(sonData);
                    }
                    BeanUtil.copyProperties(payPlanSheetEntityExt, sonSheetEntityExt);
                    sonSheetEntityExt.setAlone(SheetAloneEnum.CHILD.getCode());
                    sonSheetEntityExt.setUuid(uuid);
                    sonSheetEntityExt.setData(sonData);
                    sonSheetEntityExt.setSerialNo(sonSerialNo + i);
                    sonSheetList.add(sonSheetEntityExt);
                }
                if(!sonSheetList.isEmpty()){
                    payPlanSheetModel.insertBatch(sonSheetList);
                }
            }
        }catch (Exception e) {
            for (PayPlanSheetEntityExt planSheetEntityExt : sonSheetList) {
                paasFormSubDataModel.transferSubForm(planSheetEntityExt, IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET_SUB);
            }
            LOG.error("保存付款单明细到数据库报错", e);
            throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208053, PaymentErrorCodeEnum.API_ERROR_208053.getMsg(), XbbRefTypeEnum.PAY_SHEET.getName());
        }
        return sonSheetList;
    }
}
